import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart';

/// 加密解密工具类
/// 提供数据加密和对应的解密功能
class EncryptionUtils {
  // 固定拼接字符串
  static const String _fixedString = "GCV6bSE4PPHdVbZRmN8XJMXkPzfpRZVD";

  // AES加密参数 (实际使用中请替换为您的密钥)
  static const String _aesKey = "H2tQHEYz5DcsEQfAk2YubKDhV2NUxFvQ";
  static const String _aesIV = "daSZTpuGaMHFhR3h";

  /// 加密函数
  /// [originalDic] 原始请求字典
  /// 返回包含加密后receipt的字典
  static Map<String, dynamic> encryptData(Map<String, dynamic>? originalDic) {
    // 1. 按键排序并拼接值
    // final sortedKeys = originalDic.keys.toList()..sort();
    // final concatenatedValues = sortedKeys.map((key) => originalDic[key]).join();
    // ..sort((a, b) => a.key.compareTo(b.key));
    var concatenatedValues = '';
    if (originalDic == null || originalDic.isEmpty) {
      concatenatedValues = '';
    } else {
      //排序规则，按照key的ascall 码之和进行排序，

      // 将 map 的 entries 转为 list 然后排序
      var sortedEntries = originalDic.entries.toList()
        ..sort((a, b) => a.key.compareTo(b.key));

      // 将排序后的 entries 重新转为 map
      // Map<String, dynamic> sortedMap = {
      //   for (var entry in sortedEntries) entry.key: entry.value
      // };
      // ignore: collection_methods_unrelated_type
      concatenatedValues = sortedEntries
          // ignore: collection_methods_unrelated_type
          .map((entry) => originalDic[entry.key].toString())
          .join();
    }

    // 2. 拼接固定字符串
    final combinedString = concatenatedValues + _fixedString;
    print(' 拼接结果 Combined String: $combinedString');

    // 3. 生成MD5签名
    final sign = md5.convert(utf8.encode(combinedString)).toString();

    // 4. 构建带签名的新字典
    final newDic = {
      if (originalDic != null)
        ...originalDic.map((key, value) => MapEntry(key, value.toString())),
      'sign': sign,
    };
    // 5. AES加密和Base64处理
    final encryptedData = _aesEncrypt(json.encode(newDic));

    return {'receipt': encryptedData};
  }

  /// 解密函数
  /// [receipt] 加密后的字符串
  /// 返回解密后的原始字典(包含sign)
  static Map<String, dynamic> decryptData(String receipt) {
    // 1. 解密AES数据
    final decryptedJson = _aesDecrypt(receipt);

    // 2. 转换为JSON对象
    final decodedData = json.decode(decryptedJson);

    if (decodedData is Map<String, dynamic>) {
      return decodedData;
    } else {
      throw FormatException('解密后的数据格式不正确');
    }
  }

  /// AES加密实现
  static String _aesEncrypt(String plainText) {
    final key = Key.fromUtf8(_aesKey);
    final iv = IV.fromUtf8(_aesIV);
    final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
    final encrypted = encrypter.encrypt(plainText, iv: iv);
    return encrypted.base64;
  }

  /// AES解密实现
  static String _aesDecrypt(String encryptedText) {
    final key = Key.fromUtf8(_aesKey);
    final iv = IV.fromUtf8(_aesIV);
    final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
    final encrypted = Encrypted.fromBase64(encryptedText);
    return encrypter.decrypt(encrypted, iv: iv);
  }

  /// 验证签名是否有效
  /// 用于解密后验证数据完整性
  static bool verifySignature(Map<String, dynamic> data) {
    if (!data.containsKey('sign')) return false;

    // 复制数据并移除sign字段
    final dataWithoutSign = Map<String, String>.from(data)..remove('sign');

    // 重新计算签名
    final sortedKeys = dataWithoutSign.keys.toList()..sort();
    final concatenatedValues = sortedKeys
        .map((key) => dataWithoutSign[key])
        .join();
    final combinedString = concatenatedValues + _fixedString;
    final computedSign = md5.convert(utf8.encode(combinedString)).toString();

    // 比较签名
    return computedSign == data['sign'];
  }
}

// 使用示例
void main() {
  // 原始数据
  final originalData = {"user": "asdfasdf", "nickname": "ttttt"};

  // 加密
  final encrypted = EncryptionUtils.encryptData(originalData);
  print('加密结果: $encrypted');

  // 解密
  try {
    final decrypted = EncryptionUtils.decryptData(encrypted['receipt']!);
    print('解密结果: $decrypted');

    // 验证签名
    final isSignatureValid = EncryptionUtils.verifySignature(decrypted);
    print('签名是否有效: $isSignatureValid');
  } catch (e) {
    print('解密失败: $e');
  }
}
